package com.itheima.health.service.impl;

import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.SetmealDao;
import com.itheima.health.dto.*;
import com.itheima.health.pojo.Order;
import com.itheima.health.result.BusinessRequest;
import com.itheima.health.service.MemberService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class MemberServicelmpl implements MemberService {
    @Autowired
    private MemberDao memberDao;
    @Autowired
    private SetmealDao setmealDao;

    @Override
    /*
     * 统计分析-会员数量图表显示
     * */
    public MemberPlssParm getMemberReport() {
        MemberPlssParm memberPlssParm = new MemberPlssParm();
        List<String> stringList = new ArrayList<>();  //日期集合
        List<Integer> integerList = new ArrayList<>(); //会员数集合

        //获取到今日日期
        LocalDate todayDate = LocalDate.now(); //获取今日日期
        //获取前三个月日期,升序显示
        for (int i = 3; i >= 0; i--) {
            //获取该月的第一天
            LocalDate firstDay = LocalDate.of(todayDate.getYear(), todayDate.getMonth().minus(i), 1);
            //获取该月的最后1天
            LocalDate lastDay = firstDay.withDayOfMonth(
                    firstDay.getMonth().length(firstDay.isLeapYear())
            );
            //统计当月以及前3个月中会员增长情况,升序显示
            //根据日期查询截至当前月份末的会员数量
            stringList.add(todayDate.getYear() + "-" + todayDate.getMonth().minus(i));
            Integer thisNewMember = memberDao.getThisNewMember(firstDay, lastDay);
            integerList.add(thisNewMember);
        }
        memberPlssParm.setMonths(stringList);
        memberPlssParm.setMemberCount(integerList);
        return memberPlssParm;
    }

    /*
     * 统计分析-套餐预约占比
     * */
    @Override
    public Map<String, Object> getSetmealReport() {
        Map<String, Object> data = new HashMap<>();
        List<String> setmealNames = new ArrayList<>();
        List<Map<String, Object>> setmealCount = new ArrayList<>();

        // 调用DAO层获取套餐数据
        List<Map<String, Object>> setmealData = setmealDao.getSetmealReport();

        for (Map<String, Object> setmeal : setmealData) {
            String name = (String) setmeal.get("name");
            Long count = (Long) setmeal.get("count");

            setmealNames.add(name);

            Map<String, Object> countData = new HashMap<>();
            countData.put("name", name);
            countData.put("value", count);

            setmealCount.add(countData);
        }

        data.put("setmealNames", setmealNames);
        data.put("setmealCount", setmealCount);

        return data;
    }

    @Override
    public BusinessRequest getBusinessReportData() {
        //获取今日日期
        LocalDate reportDate = LocalDate.now();
        // 获取本周第一天
        LocalDate firstDayOfWeek = reportDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        // 获取本周最后一天
        LocalDate lastDayOfWeek = reportDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        // 获取本月第一天
        LocalDate firstDayOfMonth = reportDate.with(TemporalAdjusters.firstDayOfMonth());
        // 获取本月最后一天
        LocalDate lastDayOfMonth = reportDate.with(TemporalAdjusters.lastDayOfMonth());
        //今日新增会员数
        Integer todayNewMember = memberDao.countMemberNumber(reportDate);
        //总会员数
        Integer totalMember = memberDao.selectMemberNumber();
        //本周新增会员数
        log.info("第一天" + firstDayOfWeek + "最后一天" + lastDayOfWeek);
        LocalDateTime firstTime = LocalDateTime.of(firstDayOfWeek, LocalTime.MIN);
        LocalDateTime lastTime = LocalDateTime.of(lastDayOfWeek, LocalTime.MAX);
        Integer thisWeekNewMember = memberDao.selectByFirstTimeAndLastTime(firstTime, lastTime);
        //本月新增会员数
        LocalDateTime bengin = LocalDateTime.of(firstDayOfMonth, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(lastDayOfMonth, LocalTime.MAX);
        Integer thisMonthNewMember = memberDao.selectByFirstTimeAndLastTime(bengin, end);
        //今日预约数
        Integer todayOrderNumber = memberDao.selectOrderByTime(reportDate);
        //今日到诊数
        Integer todayVisitsNumber = memberDao.selectByStatus(reportDate, Order.ORDERSTATUS_YES);
        //本周预约数
        Integer thisWeekOrderNumber = memberDao.selectReservationNumber(firstDayOfWeek, lastDayOfWeek);
        //本周到诊数
        Integer thisWeekVisitsNumber = memberDao.selectReservationByTime(firstDayOfWeek, lastDayOfWeek, Order.ORDERSTATUS_YES);
        //本月预约数
        Integer thisMonthOrderNumber = memberDao.selectReservationNumber(firstDayOfMonth, lastDayOfMonth);
        //本月到诊数
        Integer thisMonthVisitsNumber = memberDao.selectReservationByTime(firstDayOfMonth, lastDayOfMonth, Order.ORDERSTATUS_YES);
        //热门套餐
        LocalDate todayDate = LocalDate.now();
        List<PopularPackageParam> hotSetmeal = new ArrayList<>();
        //查询今日热门套餐
        List<PopularPackageParam> popularPackageParam = memberDao.gettodaySetmeal(todayDate);
        //如果今日没有预约订单，则不显示热门套餐
        if (popularPackageParam.size() != 0) {
            //查询今日套餐总预约数，便于后期计算占比
            Integer number = memberDao.gettodayOrderNumber(todayDate);
            //double类型格式化处理器
            DecimalFormat df = new DecimalFormat("0.00");  //保留两位小数
            for (PopularPackageParam popularPackageParam1 : popularPackageParam) {
                if (popularPackageParam.size() == 1) {
                    //如果今日预约的套餐只有一个,直接set占比为1.0
                    popularPackageParam1.setProportion(1.0);
                } else {
                    //计算热门套餐占比
                    popularPackageParam1.setProportion(Double.valueOf(df.format(popularPackageParam1.getSetmeal_count() * 1.00 / number)));
                }
                hotSetmeal.add(popularPackageParam1);
            }
        }
        //封装数据
        BusinessRequest businessRequest = BusinessRequest
                .builder()
                .reportDate(reportDate)
                .todayNewMember(todayNewMember)
                .totalMember(totalMember)
                .thisWeekNewMember(thisWeekNewMember)
                .thisMonthNewMember(thisMonthNewMember)
                .todayOrderNumber(todayOrderNumber)
                .todayVisitsNumber(todayVisitsNumber)
                .thisWeekOrderNumber(thisWeekOrderNumber)
                .thisWeekVisitsNumber(thisWeekVisitsNumber)
                .thisMonthOrderNumber(thisMonthOrderNumber)
                .thisMonthVisitsNumber(thisMonthVisitsNumber)
                .hotSetmeal(hotSetmeal)
                .build();
        return businessRequest;
    }
}



